package com.atguigu.tingshu.user.service.impl;

import com.atguigu.tingshu.album.client.TrackInfoFeignClient;
import com.atguigu.tingshu.common.constant.SystemConstant;
import com.atguigu.tingshu.common.result.Result;
import com.atguigu.tingshu.model.album.TrackInfo;
import com.atguigu.tingshu.model.user.*;
import com.atguigu.tingshu.user.mapper.*;
import com.atguigu.tingshu.user.service.UserInfoService;
import com.atguigu.tingshu.user.service.UserPaidTrackService;
import com.atguigu.tingshu.user.strategy.ItemTypeStrategy;
import com.atguigu.tingshu.user.strategy.StrategyFactory;
import com.atguigu.tingshu.vo.user.UserInfoVo;
import com.atguigu.tingshu.vo.user.UserPaidRecordVo;
import com.atguigu.tingshu.vo.user.UserSubscribeVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.joda.time.LocalDateTime;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
@Service
@SuppressWarnings({"all"})
public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo> implements UserInfoService {

    @Autowired
    private UserInfoMapper userInfoMapper;
    @Autowired
    private UserPaidAlbumMapper userPaidAlbumMapper;
    @Autowired
    private UserPaidTrackService userPaidTrackService;
    @Autowired
    private UserPaidTrackMapper userPaidTrackMapper;
    @Autowired
    private UserVipServiceMapper userVipServiceMapper;
    @Autowired
    private VipServiceConfigMapper vipServiceConfigMapper;
    @Autowired
    private TrackInfoFeignClient trackInfoFeignClient;
    @Autowired
    private StrategyFactory strategyFactory;


    @Override
    public UserInfoVo getUserInfoVoByUserId(Long userId) {
        UserInfo userInfo = this.getById(userId);
        //	创建UserInfoVo 对象
        UserInfoVo userInfoVo = new UserInfoVo();
        //	属性拷贝
        BeanUtils.copyProperties(userInfo, userInfoVo);
        return userInfoVo;
    }

    @Override
    public Map<Long, Integer> userIsPaidTrack(Long userId, Long albumId, List<Long> trackIdList) {
        //	根据UserId,albumId 获取到用户付款专辑对象
        LambdaQueryWrapper<UserPaidAlbum> userPaidAlbumLambdaQueryWrapper = new LambdaQueryWrapper<>();
        userPaidAlbumLambdaQueryWrapper.eq(UserPaidAlbum::getUserId, userId).eq(UserPaidAlbum::getAlbumId, albumId);
        UserPaidAlbum userPaidAlbum = userPaidAlbumMapper.selectOne(userPaidAlbumLambdaQueryWrapper);
        //	判断
        if (null != userPaidAlbum) {
            //	创建一个map 集合
            HashMap<Long, Integer> map = new HashMap<>();
            //	如果查询到对应的专辑购买记录，则默认将声音Id 赋值为 1
            trackIdList.forEach(trackId -> {
                map.put(trackId, 1);
            });
            return map;
        } else {
            //	根据用户Id 与专辑Id 查询用户购买声音记录
            LambdaQueryWrapper<UserPaidTrack> userPaidTrackLambdaQueryWrapper = new LambdaQueryWrapper<>();
            userPaidTrackLambdaQueryWrapper.eq(UserPaidTrack::getUserId, userId).in(UserPaidTrack::getTrackId, trackIdList);
            List<UserPaidTrack> userPaidTrackList = userPaidTrackService.list(userPaidTrackLambdaQueryWrapper);
            //	获取到用户购买声音Id 集合
            List<Long> userPaidTrackIdList = userPaidTrackList.stream().map(UserPaidTrack::getTrackId).collect(Collectors.toList());
            //	创建一个map 集合
            HashMap<Long, Integer> map = new HashMap<>();
            trackIdList.forEach(trackId -> {
                if (userPaidTrackIdList.contains(trackId)) {
                    //	用户已购买声音
                    map.put(trackId, 1);
                } else {
                    map.put(trackId, 0);
                }
            });
            return map;
        }
    }

    @Override
    public Boolean isPaidAlbum(Long userId, Long albumId) {
        // 根据用户Id 与专辑Id 查询是否有记录
        Long count = userPaidAlbumMapper
                .selectCount(new LambdaQueryWrapper<UserPaidAlbum>()
                        .eq(UserPaidAlbum::getUserId, userId)
                        .eq(UserPaidAlbum::getAlbumId, albumId));
        if (count > 0) {
            return true;
        }
        return false;
    }

    @Override
    public List<Long> findUserPaidTrackList(Long userId, Long albumId) {
        // 根据用户Id 与 专辑Id 获取到已购买的声音集合
        List<UserPaidTrack> userPaidTrackList = userPaidTrackMapper
                .selectList(new LambdaQueryWrapper<UserPaidTrack>()
                        .eq(UserPaidTrack::getUserId, userId)
                        .eq(UserPaidTrack::getAlbumId, albumId));
        // 获取到已购买的声音集合Id 列表
        List<Long> trackIdList = userPaidTrackList.stream().map(UserPaidTrack::getTrackId).collect(Collectors.toList());
        // 返回集合数据
        return trackIdList;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void savePaidRecord(UserPaidRecordVo userPaidRecordVo) {
        //  根据购买类型判断向哪张表插入数据.
        if (userPaidRecordVo.getItemType().equals(SystemConstant.ORDER_ITEM_TYPE_ALBUM)) {
            //  专辑 user_paid_album
            //  防止重复添加.
            LambdaQueryWrapper<UserPaidAlbum> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(UserPaidAlbum::getUserId, userPaidRecordVo.getUserId());
            //  wrapper.eq(UserPaidAlbum::getAlbumId,userPaidRecordVo.getItemIdList().get(0));
            wrapper.eq(UserPaidAlbum::getOrderNo, userPaidRecordVo.getOrderNo());
            UserPaidAlbum userPaidAlbum = userPaidAlbumMapper.selectOne(wrapper);
            if (null != userPaidAlbum) {
                return;
            }
            //  新增：
            userPaidAlbum = new UserPaidAlbum();
            userPaidAlbum.setUserId(userPaidRecordVo.getUserId());
            userPaidAlbum.setOrderNo(userPaidRecordVo.getOrderNo());
            //  专辑Id 声音Id vip_service_config.id ==> order_detial.item_id;
            userPaidAlbum.setAlbumId(userPaidRecordVo.getItemIdList().get(0));
            userPaidAlbumMapper.insert(userPaidAlbum);
        } else if (userPaidRecordVo.getItemType().equals(SystemConstant.ORDER_ITEM_TYPE_TRACK)) {
            //  声音 user_paid_track
            LambdaQueryWrapper<UserPaidTrack> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(UserPaidTrack::getUserId, userPaidRecordVo.getUserId());
            wrapper.eq(UserPaidTrack::getOrderNo, userPaidRecordVo.getOrderNo());
            Long count = userPaidTrackMapper.selectCount(wrapper);
            if (count > 0) {
                return;
            }
            //  获取专辑Id
            Result<TrackInfo> trackInfoResult = trackInfoFeignClient.getTrackInfo(userPaidRecordVo.getItemIdList().get(0));
            TrackInfo trackInfo = trackInfoResult.getData();
            //  声音Id 有可能一次购买多个.需要循环遍历
            userPaidRecordVo.getItemIdList().stream().forEach(trackId -> {
                //  保存数据：
                UserPaidTrack userPaidTrack = new UserPaidTrack();
                userPaidTrack.setTrackId(trackId);
                userPaidTrack.setOrderNo(userPaidRecordVo.getOrderNo());
                userPaidTrack.setUserId(userPaidRecordVo.getUserId());
                //  获取专辑Id
                userPaidTrack.setAlbumId(trackInfo.getAlbumId());
                userPaidTrackMapper.insert(userPaidTrack);
            });
        } else {
            //  vip user_vip_service 保存： vip:续期
            //  获取用户对象信息.
            UserInfo userInfo = userInfoMapper.selectById(userPaidRecordVo.getUserId());
            //  系统时间
            Date currentTime = new Date();
            //  判断是否要做续期：
            if (userInfo.getIsVip().intValue() == 1 && userInfo.getVipExpireTime().after(new Date())) {
                //  续期：
                currentTime = userInfo.getVipExpireTime();
            }
            VipServiceConfig vipServiceConfig = vipServiceConfigMapper.selectById(userPaidRecordVo.getItemIdList().get(0));
            Integer serviceMonth = vipServiceConfig.getServiceMonth();
            //  LocalDate LocalDateTime LocalTime
            Date expireTime = new LocalDateTime(currentTime).plusMonths(serviceMonth).toDate();
            //  创建对象
            UserVipService userVipService = new UserVipService();
            userVipService.setOrderNo(userPaidRecordVo.getOrderNo());
            userVipService.setUserId(userPaidRecordVo.getUserId());
            userVipService.setStartTime(new Date());
            //--------------> 购买的时长:
            userVipService.setExpireTime(expireTime);
            //  保存
            userVipServiceMapper.insert(userVipService);
            //  修改user_info.is_vip=1;
            userInfo.setIsVip(1);
            //  设置过期时间
            userInfo.setVipExpireTime(expireTime);
            //  手动模拟异常信息。
            //  int i = 1/0;
            //  修改
            this.userInfoMapper.updateById(userInfo);
        }
    }
    //处理用户购买记录（虚拟物品发货）
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void userPayRecord(UserPaidRecordVo userPaidRecordVo) {
        //从策略工厂中获取对应的策略对象
        ItemTypeStrategy strategy = strategyFactory.getStrategy(userPaidRecordVo.getItemType());
        //执行策略对象的任务
        strategy.savePaidRecord(userPaidRecordVo);
    }

    @Override
    public void updateVipExpireStatus() {
        //	获取到当前时间
        userInfoMapper.updateIsVip();
    }

    @Override
    public IPage<UserSubscribeVo> findUserSubscribePage(Page<UserSubscribeVo> subscribeVoPage, UserSubscribe userSubscribe) {
        return userInfoMapper.selectUserSubscribePage(subscribeVoPage,userSubscribe);
    }
}
